package com.tbit.uqbike.client.service.impl;

import com.tbit.common.constant.BusinessConstant;
import com.tbit.common.constant.OperationPlatform;
import com.tbit.common.entity.UserOpLog;
import com.tbit.uqbike.client.business.user_op_log.service.UserOpLogService;
import com.tbit.uqbike.client.constant.enums.GiftCardType;
import com.tbit.uqbike.client.dao.core.AccountDao;
import com.tbit.uqbike.client.dao.core.AgentDepositVipDao;
import com.tbit.uqbike.client.dao.core.GiftCardDao;
import com.tbit.uqbike.client.dao.core.UserDao;
import com.tbit.uqbike.client.dao.log.RechargeGiveLogDao;
import com.tbit.uqbike.client.exception.BaseException;
import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.service.*;
import com.tbit.uqbike.client.util.DateTimeUtil;
import com.tbit.uqbike.client.util.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @Author: chen
 * @Description: 礼品卡
 * @Date: 创建于 10:57 2020/1/6
 */
@Slf4j
@Service("giftCardService")
public class GiftCardServiceImpl implements GiftCardService {
    @Autowired
    private GiftCardDao giftCardDao;
    @Autowired
    private GiftCardUserService giftCardUserService;
    @Autowired
    private UserAccountLogService userAccountLogService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private AgentDepositVipDao agentDepositVipDao;
    @Autowired
    private UserToAgentService userToAgentService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private CouponUserService couponUserService;
    @Autowired
    private RechargeGiveLogDao rechargeGiveLogDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserOpLogService userOpLogService;
    @Autowired
    private AccountDao accountDao;

    @Override
    @Transactional
    public void edit(GiftCard giftCard, User user) {
        log.info("[礼品卡兑换] 入参={}", giftCard);
        giftCard.setUseTime(DateTimeUtil.getNowTime());
        GiftCard giftCardDB = getByCarNO(giftCard.getCardNO());
        if (giftCardDB == null) {
            throw new BaseException("-130001", "兑换码不存在");
        }
        if (DateTimeUtil.getTimeDF(giftCardDB.getExpireDate(), DateTimeUtil.getNowTime()) > 0) {
            throw new BaseException("-130002", "兑换码已失效");
        }

        if (giftCardDB.getUseTime() != null) {
            throw new BaseException("-130003", "兑换码已使用");
        }
        Integer brandId = accountDao.getBrandId(giftCardDB.getAccountId());
        if (!Objects.equals(brandId, user.getAccountId())) {
            //兑换的礼品卡和用户使用的礼品卡不一致
            throw new BaseException("-130001", "兑换码不存在");
        }

        // 兼容礼品卡兑换添加免押套餐功能
        if (giftCardDB.getMemberFeeDays() != null && giftCardDB.getMemberFeeDays() != 0) {
            Map<String, Object> map = new HashMap<>();
            map.put("userId", giftCard.getUserId());
            map.put("accountId", giftCardDB.getAccountId());
            AgentDepositVip agentDepositVipDB = agentDepositVipDao.getByUserId(map);
            String date;
            if (agentDepositVipDB != null &&
                    DateTimeUtil.getTimeDF(DateTimeUtil.getNowTime(), agentDepositVipDB.getExpireDt() + " 23:59:59") > 0) {
                date = DateTimeUtil.DateTimeToString(DateTimeUtil
                        .addDay(DateTimeUtil.StringToDateTime(agentDepositVipDB.getExpireDt() + " 23:59:59"), giftCardDB.getMemberFeeDays()));
            } else {
                date = DateTimeUtil.DateTimeToString(DateTimeUtil.addDay(new Date(), giftCardDB.getMemberFeeDays()));
            }
            AgentDepositVip agentDepositVip = new AgentDepositVip();
            agentDepositVip.setUserId(giftCard.getUserId());
            agentDepositVip.setAccountId(giftCardDB.getAccountId());
            agentDepositVip.setLastUpdateDt(DateTimeUtil.getNowTime());
            agentDepositVip.setExpireDt(date);
            agentDepositVipDao.insert(agentDepositVip);
            log.info("赠送免押会员,用户id=" + giftCard.getUserId());
        }
        giftCardDao.edit(giftCard);

        GiftCardType giftCardType = GiftCardType.of(giftCardDB.getCardType());
        switch (giftCardType) {
            case GIFT_CASH:
                exchangeMoney(giftCard.getUserId(), giftCardDB);
                break;
            case COUPON:
                exchangeCoupon(giftCard.getUserId(), giftCardDB);
                break;
        }
    }

    // 兑换优惠券
    private void exchangeCoupon(Integer userId, GiftCard giftCardDB) {
        Coupon coupon = couponService.getByCouponId(giftCardDB.getCouponId());
        if (coupon == null) {
            throw new BaseException("-130004", "优惠券不存在");
        }
        List<CouponUser> couponUsers = new ArrayList<>(giftCardDB.getCouponCount());
        String now = DateTimeUtil.getNowTime();
        for (int i = 0; i < giftCardDB.getCouponCount(); i++) {
            CouponUser couponUser = new CouponUser();
            couponUser.setCouponId(coupon.getCouponId());
            couponUser.setAccountId(giftCardDB.getAccountId());
            couponUser.setUserId(userId);
            couponUser.setRecTime(now);
            couponUser.setIsUse(0);
            couponUser.setIsValid(1);
            couponUser.setExpireTime(DateTimeUtil.DateTimeToString(DateTimeUtil.addDay(new Date(), giftCardDB.getCouponExpireDays())));
            couponUsers.add(couponUser);
        }

        User user = userDao.getByUserId(userId);

        RechargeGiveLog rechargeGiveLog = new RechargeGiveLog();
        rechargeGiveLog.setAccountId(coupon.getAccountId());
        rechargeGiveLog.setUserId(userId);
        rechargeGiveLog.setRechargeMoney(0);
        rechargeGiveLog.setRechargeTime(new Date());
        rechargeGiveLog.setGiveMoney(0);
        rechargeGiveLog.setUserName(user == null ? "" : user.getName());
        rechargeGiveLog.setUserPhone(user == null ? "" : user.getPhone());
        rechargeGiveLog.setBaseMoney(0);
        rechargeGiveLog.setCouponId(coupon.getCouponId());
        rechargeGiveLog.setCouponCount(giftCardDB.getCouponCount());
        rechargeGiveLog.setRemark("礼品卡兑换优惠券");

        couponUserService.addBatch(couponUsers);
        log.info("[礼品卡兑换] 用户id={}兑换优惠券,优惠券id={},数量={}", userId, coupon.getCouponId(), giftCardDB.getCouponCount());
        rechargeGiveLogDao.insert(rechargeGiveLog);

        // 插入用户操作日志
        userOpLogService.insertSingle(UserOpLog.builder()
                .accountId(user.getAccountId())
                .opUser(user.getName())
                .opUserPhone(user.getPhone())
                .targetUser(user.getName())
                .targetUserPhone(user.getPhone())
                .operation("礼品卡变动")
                .opType("用户使用")
                .opPlatform(OperationPlatform.CLIENT.code)
                .opTime(LocalDateTime.now())
                .result(true)
                .detail("礼品卡ID: " + giftCardDB.getGiftcardId() + "\n兑换优惠券ID: " + giftCardDB.getCouponId()+ "\n优惠券数量: " + giftCardDB.getCouponCount())
                .build());
    }

    // 兑换礼品金
    private void exchangeMoney(Integer userId, GiftCard giftCardDB) {
        /**添加到用户余额*/
        String dateTime = DateTimeUtil.getNowTime();
        GiftCardUser giftCardUser = new GiftCardUser();
        giftCardUser.setUserId(userId);
        giftCardUser.setAccountId(giftCardDB.getAccountId());
        giftCardUser.setMoney(giftCardDB.getMoney());
        giftCardUser.setUpdateTime(dateTime);
        giftCardUserService.insert(giftCardUser, "礼品卡兑换金额", BusinessConstant.BUSINESS_GIF_EXCHANGE, "", dateTime);
        /**建立用户区域绑定关系*/
        userToAgentService.insert(userId, giftCardDB.getAccountId());

        /** 添加金额变动日志 */
        UserAccountLog userAccountLog = new UserAccountLog();
        userAccountLog.setAccountId(giftCardDB.getAccountId());
        userAccountLog.setUserId(userId);
        userAccountLog.setOperaTime(DateTimeUtil.getNowTime());
        userAccountLog.setMoney((double) giftCardDB.getMoney());
        userAccountLog.setMoneyType(1);
        userAccountLog.setType(1);
        userAccountLog.setRemark("礼品卡兑换金额");
        log.info("[礼品卡兑换] 用户id={}兑换礼品金,金额={}", userId, giftCardDB.getMoney());
        userAccountLogService.insert(userAccountLog);

        // 插入用户操作日志
        User user = userDao.getByUserId(userId);
        userOpLogService.insertSingle(UserOpLog.builder()
                .accountId(user.getAccountId())
                .opUser(user.getName())
                .opUserPhone(user.getPhone())
                .targetUser(user.getName())
                .targetUserPhone(user.getPhone())
                .operation("礼品卡变动")
                .opType("用户使用")
                .opPlatform(OperationPlatform.CLIENT.code)
                .opTime(LocalDateTime.now())
                .result(true)
                .detail("礼品卡ID: " + giftCardDB.getGiftcardId() + "\n兑换礼品金金额: " + giftCardDB.getMoney() / 100d + "元")
                .build());
    }

    @Override
    public GiftCard getByCarNO(String cardNO) {
        Map<String, Object> map = new HashMap<>();
        map.put("cardNO", cardNO);
        return giftCardDao.getByCarNO(map);
    }

    @Override
    public List<GiftCard> getByUserId(Integer accountId, Integer userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("accountId", accountId);
        return giftCardDao.getByUserId(map);
    }
}
